#include "include.h"

#if ENERGY_LED_EN    //能量灯软件PWM输出.

#define  ENERGY_LED_NUM 4         //灯的个数
#define  ENERGY_PWM_MAX_DUTY  8   //一个灯分8个亮度.

#define  ENERGY_LED_INIT()     {GPIOBDE |= 0x0F; GPIOBDIR &= ~0x0F;}
#define  ENERGY_LED_0_ON()     GPIOBSET = BIT(0)
#define  ENERGY_LED_0_OFF()    GPIOBCLR = BIT(0)
#define  ENERGY_LED_1_ON()     GPIOBSET = BIT(1)
#define  ENERGY_LED_1_OFF()    GPIOBCLR = BIT(2)
#define  ENERGY_LED_2_ON()     GPIOBSET = BIT(2)
#define  ENERGY_LED_2_OFF()    GPIOBCLR = BIT(2)
#define  ENERGY_LED_3_ON()     GPIOASET = BIT(3)
#define  ENERGY_LED_3_OFF()    GPIOACLR = BIT(3)

u8 pwm_duty_buf[ENERGY_LED_NUM];

AT(.com_text.rgb.tbl)   //非线性量化表.
u8 const energy_qtz_tbl[4 * 8] = {
     1,14,18,22,26,30,35,40,
     41,43,46,48,51,53,56,60,
     61,63,66,68,71,73,76,80,
     81,83,85,88,91,93,96,100,
};

void energy_led_init(void)
{
    ENERGY_LED_INIT();
}

AT(.com_text.rgb)
void energy_led_level_calc(void)    //约5ms调用一次.
{
    u8 level,i;
    u16 energy;
    static u8 disp_level,last_level;
    static u8 time_5ms_cnt = 0;

    time_5ms_cnt++;
    if(time_5ms_cnt >= 4){   //20ms计算一次能量
        time_5ms_cnt  = 0;

        energy = dac_pcm_pow_calc();
        //printf("[%X_%d]",rgb_led_en,energy);
        if (FUNC_MUSIC == func_cb.sta) {   //各模式能量效果可能不一样.
            energy = energy/450;
        } else if (FUNC_FMRX == func_cb.sta) {
            energy = energy/350;
        } else{
            energy = energy/300;
        }
        //非线性量化表
        for (i = 0, last_level = 0; i < 4*8; i++) {
           if (energy < energy_qtz_tbl[i]) {
               break;
           }
           last_level++;
        }
    }
    //能量相同, 不用更新
    if(disp_level == last_level){
        return;
    }

    //能量减少时,慢慢下降
    if (disp_level > last_level) {
        disp_level--;
    } else {
        disp_level = last_level;
    }

    //能量转为占空比,存放到pwm_duty_buf中.
    level = disp_level;
    for (i=0; i<ENERGY_LED_NUM; i++){
        if (level >= ENERGY_PWM_MAX_DUTY) {
            pwm_duty_buf[i] = 0;
            level -= ENERGY_PWM_MAX_DUTY;
        } else {
            pwm_duty_buf[i] = (1<<level) - 1;
            pwm_duty_buf[i] = ~pwm_duty_buf[i];
            level = 0;
        }
    }
}

AT(.com_text.rgb)
void energy_led_scan(void)  //建议1ms扫描一次.
{
    static u8 scan_bit = 0;
    if (pwm_duty_buf[0] & BIT(scan_bit)){
        ENERGY_LED_0_OFF();
    } else {
        ENERGY_LED_0_ON();
    }

    if (pwm_duty_buf[1] & BIT(scan_bit)) {
        ENERGY_LED_1_OFF();
    } else {
        ENERGY_LED_1_ON();
    }

    if (pwm_duty_buf[2] & BIT(scan_bit)) {
        ENERGY_LED_2_OFF();
    } else {
        ENERGY_LED_2_ON();
    }

    if (pwm_duty_buf[3] & BIT(scan_bit)) {
        ENERGY_LED_3_OFF();
    } else {
        ENERGY_LED_3_ON();
    }

    if (++scan_bit >= ENERGY_PWM_MAX_DUTY){ //ENERGY_PWM_MAX_DUTY= 8
        scan_bit = 0;
    }
}
#endif // ENERGY_LED_EN

